package com.gohome.gohomechat;

import android.app.ActivityManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Pair;
import android.util.Log;
import android.view.View;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;

import com.easemob.EMCallBack;
import com.easemob.EMEventListener;
import com.easemob.EMGroupChangeListener;
import com.easemob.EMNotifierEvent;
import com.easemob.chat.EMChat;
import com.easemob.chat.EMChatManager;
import com.easemob.chat.EMChatOptions;
import com.easemob.chat.EMContact;
import com.easemob.chat.EMContactListener;
import com.easemob.chat.EMContactManager;
import com.easemob.chat.EMConversation;
import com.easemob.chat.EMGroupManager;
import com.easemob.chat.EMMessage;
import com.easemob.chat.ImageMessageBody;
import com.easemob.chat.LocationMessageBody;
import com.easemob.chat.TextMessageBody;

import com.gohome.gohomechat.application.BaseApplication;

import com.easemob.chat.VoiceMessageBody;

import com.gohome.gohomechat.db.GoHomeDBTools;
import com.gohome.gohomechat.model.entify.Contant;
import com.gohome.gohomechat.model.entify.Friend;
import com.gohome.gohomechat.model.entify.Notice;
import com.gohome.gohomechat.ui.activity.ChatActivity;
import com.gohome.gohomechat.ui.activity.MainActivity;
import com.gohome.gohomechat.ui.fragment.SessionFragment;
import com.gohome.gohomechat.utils.FaceConversionUtil;
import com.parse.Parse;


import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Hashtable;
import java.io.File;
import java.util.Iterator;
import java.util.List;

/**
 * Created by dllo on 16/3/3.
 */
public class GoHomeHelper {
    private static GoHomeHelper helper;
    private Context context;
    private boolean isGroupAndContactListenerRegisted = false;
    private ActivityManager activityManager;
    private LocalBroadcastManager broadcastManager;
    private String userName = "3";
    private InputMethodManager mInputMethodManager;//定义键盘管理者

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public synchronized static GoHomeHelper getInstance() {
        if (helper == null)
            helper = new GoHomeHelper();
        return helper;
    }

    public void init(Context context) {
        this.context = context;

        FaceConversionUtil.getInstace().getFileText(context);
        this.activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        broadcastManager = LocalBroadcastManager.getInstance(context);

        int pid = android.os.Process.myPid();
        String processAppName = getAppName(pid);
// 如果app启用了远程的service，此application:onCreate会被调用2次
// 为了防止环信SDK被初始化2次，加此判断会保证SDK被初始化1次
// 默认的app会在以包名为默认的process name下运行，如果查到的process name不是app的process name就立即返回
        if (processAppName == null || !processAppName.equalsIgnoreCase("com.gohome.gohomechat")) {
            //"com.easemob.chatuidemo"为demo的包名，换到自己项目中要改成自己包名
            // 则此application::onCreate 是被service 调用的，直接返回
            return;
        }

        Parse.initialize(context);
        GoHomeModel.init();
        GoHomeDBTools.init(BaseApplication.getContext());
        EMChatManager.getInstance().getChatOptions().setUseRoster(true);
        EMChat.getInstance().setAutoLogin(true);
        EMChat.getInstance().init(context);
        EMChatOptions options = EMChatManager.getInstance().getChatOptions();
        options.setAcceptInvitationAlways(false);
        options.setUseRoster(true);
        /**
         * debugMode == true 时为打开，sdk 会在log里输入调试信息
         * @param debugMode
         * 在做代码混淆的时候需要设置成false
         */
        mInputMethodManager = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
        EMChat.getInstance().setDebugMode(true);
        EMChat.getInstance().setAppInited();
        setGlobalListeners();
        //注册消息事件监听
        registerEventListener();
    }

    /***/
    public Bitmap getCurrentUserHead() {
        if (GoHomeModel.getInstance().getHeadByte() != null) {
            Log.i("wcl", "更换头像");
            Bitmap bitmap = BitmapFactory.decodeByteArray(GoHomeModel.getInstance().getHeadByte(), 0, GoHomeModel.getInstance().getHeadByte().length);
            return bitmap;
        }
        return null;
    }

    /**
     * 键盘的显示
     */
    public void showKeyboard(EditText editText) {
        mInputMethodManager.showSoftInput(editText, InputMethodManager.SHOW_FORCED);
    }

    /**
     * 隐藏键盘
     */
    public void hideKeyboard(EditText editText) {
        mInputMethodManager.hideSoftInputFromWindow(editText.getWindowToken(), 0); //强制隐藏键盘
    }

    /**
     * 消息监听事件
     */
    private void registerEventListener() {
        EMChatManager.getInstance().registerEventListener(
                new EMEventListener() {

                    @Override
                    public void onEvent(EMNotifierEvent event) {

                        switch (event.getEvent()) {
                            case EventNewMessage: // 接收新消息
                            {
                                EMMessage message = (EMMessage) event.getData();
                                broadcastManager.sendBroadcast(new Intent(ChatActivity.NEWMessage));

                                break;
                            }
                            case EventDeliveryAck: {//接收已发送回执

                                break;
                            }

                            case EventNewCMDMessage: {//接收透传消息

                                break;
                            }

                            case EventReadAck: {//接收已读回执

                                break;
                            }

                            case EventOfflineMessage: {//接收离线消息
                                List<EMMessage> messages = (List<EMMessage>) event.getData();
                                break;
                            }

                            case EventConversationListChanged: {//通知会话列表通知event注册（在某些特殊情况，SDK去删除会话的时候会收到回调监听）
                                broadcastManager.sendBroadcast(new Intent(SessionFragment.NEWMESSAGENOTICE));
                                break;
                            }

                            default:
                                break;
                        }
                    }
                }
        );
    }

    private String getAppName(int pID) {
        String processName = null;
        ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        List l = am.getRunningAppProcesses();
        Iterator i = l.iterator();
        PackageManager pm = context.getPackageManager();
        while (i.hasNext()) {
            ActivityManager.RunningAppProcessInfo info = (ActivityManager.RunningAppProcessInfo) (i.next());
            try {
                if (info.pid == pID) {
                    CharSequence c = pm.getApplicationLabel(pm.getApplicationInfo(info.processName, PackageManager.GET_META_DATA));
                    // Log.d("Process", "Id: "+ info.pid +" ProcessName: "+
                    // info.processName +"  Label: "+c.toString());
                    // processName = c.toString();
                    processName = info.processName;
                    return processName;
                }
            } catch (Exception e) {
                // Log.d("Process", "Error>> :"+ e.toString());
            }
        }
        return processName;
    }

    /**
     * 设置全局监听
     */
    protected void setGlobalListeners() {
        registerGroupAndContactListener();
    }

    /**
     * 注册群组和联系人监听,由于
     */
    public void registerGroupAndContactListener() {
        if (!isGroupAndContactListenerRegisted) {
            //注册群组变动监听
            EMGroupManager.getInstance().addGroupChangeListener(new MyGroupChangeListener());
            //注册联系人变动监听
            EMContactManager.getInstance().setContactListener(new MyContactListener());
            isGroupAndContactListenerRegisted = true;
        }
    }


    /**
     * 群组变动监听
     */
    public class MyGroupChangeListener implements EMGroupChangeListener {
        @Override
        public void onInvitationReceived(String groupId, String groupName, String inviter, String reason) {

        }

        @Override
        public void onApplicationReceived(String groupId, String groupName, String applyer, String reason) {

        }

        @Override
        public void onApplicationAccept(String groupId, String groupName, String accepter) {

        }

        @Override
        public void onApplicationDeclined(String groupId, String groupName, String decliner, String reason) {

        }

        @Override
        public void onInvitationAccpted(String groupId, String inviter, String reason) {

        }

        @Override
        public void onInvitationDeclined(String groupId, String invitee, String reason) {

        }

        @Override
        public void onUserRemoved(String groupId, String groupName) {
        }

        @Override
        public void onGroupDestroy(String groupId, String groupName) {

        }
    }

    /**
     * 好有变化监听
     */
    public class MyContactListener implements EMContactListener {
        @Override
        public void onContactAgreed(String username) {

            GoHomeDBTools.getInstance().updateMessageStatus(username, Contant.MESSAGESTATUS_BEAGREED);
            //  if(isRunningMainActivity()){
            broadcastManager.sendBroadcast(new Intent(Contant.ACTION_CONTACT_CHANAGED));
            //  }else{}
        }

        @Override
        public void onContactRefused(String username) {
            //好友请求被拒绝
            GoHomeDBTools.getInstance().updateMessageStatus(username, Contant.MESSAGESTATUS_BEREFUSED);
            broadcastManager.sendBroadcast(new Intent(Contant.ACTION_CONTACT_REFUSED));
        }

        @Override
        public void onContactInvited(String username, String reason) {
            //收到好友邀请

            Notice notice = new Notice();

            notice.setUserName(username);
            notice.setReason(reason);
            notice.setMessageStatus(Contant.MESSAGESTATUS_BEINVITEED);
            GoHomeDBTools.getInstance().insert(notice);
            broadcastManager.sendBroadcast(new Intent(Contant.NEW_FRIENDS_INVITATION));
        }

        @Override
        public void onContactDeleted(List<String> usernameList) {
            //被删除时回调此方法
            broadcastManager.sendBroadcast(new Intent(Contant.ACCOUNT_REMOVED));

        }


        @Override
        public void onContactAdded(final List<String> usernameList) {
            //增加了联系人时回调此方法
            new Thread(new Runnable() {
                @Override
                public void run() {
                    if (usernameList.size() > 0) {
                        for (String s : usernameList) {
                            if (GoHomeDBTools.getInstance() != null && GoHomeDBTools.getInstance().queryName_friend(s) == 0) {
                                Friend friend = new Friend();
                                friend.setUserName(s);
                                GoHomeDBTools.getInstance().insert_friend(friend);
                            }
                        }
                        broadcastManager.sendBroadcast(new Intent(Contant.NEW_FRIENDS_ADD));
                    }
                }
            }).start();

        }
    }

    public boolean isRunningNoticeActivity() {

        ComponentName componentName = activityManager.getRunningTasks(1).get(0).topActivity;
        String packageName = componentName.getPackageName();
        String noticeActivity = "com.gohome.gohomechat.ui.activity.NoticeActivity";
        String className = componentName.getClassName();
        if (noticeActivity.equals(className))
            return true;
        System.out.println("package = " + packageName + ", class = " + className);
        return false;
    }

    public void sendTXTMessage(String username, String content, EMMessage.ChatType type) {
        //获取到与聊天人的会话对象。参数username为聊天人的userid或者groupid，后文中的username皆是如此
        EMConversation conversation = EMChatManager.getInstance().getConversation(username);
//创建一条文本消息
        EMMessage message = EMMessage.createSendMessage(EMMessage.Type.TXT);
//如果是群聊，设置chattype,默认是单聊
        message.setChatType(type);
//设置消息body
        TextMessageBody txtBody = new TextMessageBody(content);
        message.addBody(txtBody);
//设置接收人
        message.setReceipt(username);
//把消息加入到此会话对象中
        conversation.addMessage(message);
//发送消息
        EMChatManager.getInstance().sendMessage(message, new EMCallBack() {
            @Override
            public void onSuccess() {

            }

            @Override
            public void onError(int i, String s) {

            }

            @Override
            public void onProgress(int i, String s) {

            }
        });
    }

    /**
     * 发送语音消息
     */
    public void sendVoiceMessage(String filePath, int length) {
        EMConversation conversation = EMChatManager.getInstance().getConversation(userName);
        EMMessage message = EMMessage.createSendMessage(EMMessage.Type.VOICE);
//如果是群聊，设置chattype,默认是单聊
        message.setChatType(EMMessage.ChatType.Chat);
        VoiceMessageBody body = new VoiceMessageBody(new File(filePath), length);
        message.addBody(body);
        message.setReceipt(userName);
        conversation.addMessage(message);
        EMChatManager.getInstance().sendMessage(message, new EMCallBack(){
            @Override
            public void onSuccess() {
                Log.e("GoHomeHelper", "success");
            }

            @Override
            public void onError(int i, String s) {
                Log.e("GoHomeHelper", "error");
            }

            @Override
            public void onProgress(int i, String s) {
                Log.d("GoHomeHelper", "progress");
            }
        });
    }

    /**
     *
     *
     * */

    public void sendLocationMessage(String username,String locationAddress,double latitude,double longitude,EMMessage.ChatType type){
        EMConversation conversation = EMChatManager.getInstance().getConversation(username);
        EMMessage message = EMMessage.createSendMessage(EMMessage.Type.LOCATION);
//如果是群聊，设置chattype,默认是单聊
        message.setChatType(type);
        LocationMessageBody locBody = new LocationMessageBody(locationAddress, latitude, longitude);
        message.addBody(locBody);
        message.setReceipt(username);
        conversation.addMessage(message);
        EMChatManager.getInstance().sendMessage(message, new EMCallBack(){
            @Override
            public void onSuccess() {
                Log.e("Location", "Success");
            }

            @Override
            public void onError(int i, String s) {
                Log.e("Location", "Error");
            }

            @Override
            public void onProgress(int i, String s) {
                Log.e("GoHomeHelper", "Progress");
            }
        });
    }

    /**
     * 发送ImageMsg
     */
    public void sendImageMessage(String username, String filePath, EMMessage.ChatType type) {
        EMConversation conversation = EMChatManager.getInstance().getConversation(username);
        EMMessage message = EMMessage.createSendMessage(EMMessage.Type.IMAGE);
//如果是群聊，设置chattype,默认是单聊
        message.setChatType(type);

        ImageMessageBody body = new ImageMessageBody(new File(filePath));
// 默认超过100k的图片会压缩后发给对方，可以设置成发送原图
        body.setSendOriginalImage(true);
        message.addBody(body);
        message.setReceipt(username);
        conversation.addMessage(message);
        EMChatManager.getInstance().sendMessage(message, new EMCallBack() {
            @Override
            public void onSuccess() {
                Log.d("GoHomeHelper", "imgSendSuccess");

                broadcastManager.sendBroadcast(new Intent(ChatActivity.NEWMessage));
            }

            @Override
            public void onError(int i, String s) {
                Log.d("GoHomeHelper", "imgSendError");
            }

            @Override
            public void onProgress(int i, String s) {
                Log.d("GoHomeHelper", "Progress");
            }
        });
    }


    public void sendVedioMessage(String username, String filePath, EMMessage.ChatType type, int len) {
        // 发送语音
        EMConversation conversation = EMChatManager.getInstance().getConversation(username);
        EMMessage message = EMMessage.createSendMessage(EMMessage.Type.VOICE);
        VoiceMessageBody body = new VoiceMessageBody(new File(filePath), len);
        message.addBody(body);
        message.setReceipt(username);
        conversation.addMessage(message);
        EMChatManager.getInstance().sendMessage(message, new EMCallBack() {
            @Override
            public void onSuccess() {
                broadcastManager.sendBroadcast(new Intent(ChatActivity.NEWMessage));
            }

            @Override
            public void onError(int i, String s) {
                Log.d("GoHomeHelper", "vedioSendError");
            }

            @Override
            public void onProgress(int i, String s) {
                Log.d("GoHomeHelper", "Progress");
            }
        });
    }

    /**
     * 获得聊天记录
     */
    public List<EMMessage> obtainChatRecord(String username) {
        EMConversation conversation = EMChatManager.getInstance().getConversation(username);
//获取此会话的所有消息
        List<EMMessage> messages = conversation.getAllMessages();
        return messages;
    }

//    /**
//     * 获取20条聊天记录
//     */
//    public List<EMMessage> obtainChatRecord(String username, EMMessage.ChatType type) {
//        EMConversation conversation = EMChatManager.getInstance().getConversation(username);
//
//        if (EMMessage.ChatType.Chat == type) {
////sdk初始化加载的聊天记录为20条，到顶时需要去db里获取更多
////获取startMsgId之前的pagesize条消息，此方法获取的messages sdk会自动存入到此会话中，app中无需再次把获取到的messages添加到会话中
//              List<EMMessage> messages = conversation.loadMoreMsgFromDB(startMsgId, pagesize);
//              return messages;
//        } else {
////如果是群聊，调用下面此方法
//                  List<EMMessage> messages = conversation.loadMoreGroupMsgFromDB(startMsgId, pagesize);
//                 return messages;
//        }
//    }


    /**
     * 获取会话列表
     *
     * @return
     */
    public List<EMConversation> loadConversationList() {
        // 获取所有会话，包括陌生人
        Hashtable<String, EMConversation> conversations = EMChatManager.getInstance().getAllConversations();

        // 过滤掉messages size为0的conversation
        /**
         * 如果在排序过程中有新消息收到，lastMsgTime会发生变化
         * 影响排序过程，Collection.sort会产生异常
         * 保证Conversation在Sort过程中最后一条消息的时间不变
         * 避免并发问题
         */
        List<Pair<Long, EMConversation>> sortList = new ArrayList<Pair<Long, EMConversation>>();
        // 同步
        synchronized (conversations) {
            for (EMConversation conversation : conversations.values()) {
                if (conversation.getAllMessages().size() != 0) {
                    //if(conversation.getType() != EMConversationType.ChatRoom){
                    sortList.add(new Pair<Long, EMConversation>(conversation.getLastMessage().getMsgTime(), conversation));
                    //}
                }
            }
        }
        try {
            // Internal is TimSort algorithm, has bug
            sortConversationByLastChatTime(sortList);
        } catch (Exception e) {
            e.printStackTrace();
        }
        List<EMConversation> list = new ArrayList<EMConversation>();
        for (Pair<Long, EMConversation> sortItem : sortList) {
            list.add(sortItem.second);
        }
        return list;
    }

    /**
     * 根据最后一条消息的时间排序
     * comparator类是比较用的
     */
    private void sortConversationByLastChatTime(List<Pair<Long, EMConversation>> conversationList) {
        Collections.sort(conversationList, new Comparator<Pair<Long, EMConversation>>() {
            @Override
            public int compare(final Pair<Long, EMConversation> con1, final Pair<Long, EMConversation> con2) {

                if (con1.first == con2.first) {
                    return 0;
                } else if (con2.first > con1.first) {
                    return 1;
                } else {
                    return -1;
                }
            }

        });
    }

    /**
     * 标记消息已读
     */
    public void readMessage(String username) {
        EMConversation conversation = EMChatManager.getInstance().getConversation(username);
        conversation.markAllMessagesAsRead();
    }

    /**
     * 删除单个聊天记录
     */
    public void deleteConversation(String username) {
        //删除和某个user的整个的聊天记录(包括本地)
        EMChatManager.getInstance().deleteConversation(username);

    }

    /**
     * 删除某条聊天记录
     */
    public void deleteMessage(String username, String msg) {
        //删除当前会话的某条聊天记录
        EMConversation conversation = EMChatManager.getInstance().getConversation(username);
        conversation.removeMessage(msg);
    }
}
